/* * Requires Google Play Services * Doesn't run on emulator */ package course.examples.Location.GetLocation; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Locale; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import android.app.Activity; import android.graphics.Color; import android.location.Location; import android.os.Bundle; import android.util.Log; import android.widget.TextView; import com.google.android.gms.common.ConnectionResult; import com.google.android.gms.common.GooglePlayServicesClient; import com.google.android.gms.common.GooglePlayServicesUtil; import com.google.android.gms.location.LocationClient; import com.google.android.gms.location.LocationListener; import com.google.android.gms.location.LocationRequest; public class LocationGetLocationActivity extends Activity implements GooglePlayServicesClient.ConnectionCallbacks, GooglePlayServicesClient.OnConnectionFailedListener, LocationListener { private static final long ONE_MIN = 1000 * 60; private static final long TWO_MIN = ONE_MIN * 2; private static final long FIVE_MIN = ONE_MIN * 5; private static final long MEASURE_TIME = 1000 * 30; private static final long POLLING_FREQ = 1000 * 10; private static final long FASTES_UPDATE_FREQ = 1000 * 2; private static final float MIN_ACCURACY = 25.0f; private static final float MIN_LAST_READ_ACCURACY = 500.0f; // Define an object that holds accuracy and frequency parameters LocationRequest mLocationRequest; // Views for display location information private TextView mAccuracyView; private TextView mTimeView; private TextView mLatView; private TextView mLngView; private int mTextViewColor = Color.GRAY; // Current best location estimate private Location mBestReading; private final String TAG = "LocationGetLocationActivity"; private boolean mFirstUpdate = true; private LocationClient mLocationClient; private Location mCurrentLocation; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (!servicesAvailable()) finish(); setContentView(R.layout.main); mAccuracyView = (TextView) findViewById(R.id.accuracy_view); mTimeView = (TextView) findViewById(R.id.time_view); mLatView = (TextView) findViewById(R.id.lat_view); mLngView = (TextView) findViewById(R.id.lng_view); // Create new Location Client. This class will handle callbacks mLocationClient = new LocationClient(this, this, this); // Create and define the LocationRequest mLocationRequest = LocationRequest.create(); // Use high accuracy mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); // Update every 10 seconds mLocationRequest.setInterval(POLLING_FREQ); // Recieve updates no more often than every 2 seconds mLocationRequest.setFastestInterval(FASTES_UPDATE_FREQ); } @Override protected void onStart() { super.onStart(); // Connect to LocationServices mLocationClient.connect(); } @Override protected void onStop() { // Stop updates mLocationClient.removeLocationUpdates(this); // Disconnect from LocationServices mLocationClient.disconnect(); super.onStop(); } // Called back when location changes @Override public void onLocationChanged(Location location) { ensureColor(); // Determine whether new location is better than current best // estimate if (null == mBestReading || location.getAccuracy() < mBestReading.getAccuracy()) { // Update best estimate mBestReading = location; // Update display updateDisplay(location); if (mBestReading.getAccuracy() < MIN_ACCURACY) mLocationClient.removeLocationUpdates(this); } } @Override public void onConnected(Bundle dataBundle) { // Get first reading. Get additional location updates if necessary if (servicesAvailable()) { // Get best last location measurement meeting criteria mBestReading = bestLastKnownLocation(MIN_LAST_READ_ACCURACY, FIVE_MIN); // Display last reading information if (null != mBestReading) { updateDisplay(mBestReading); } else { mAccuracyView.setText("No Initial Reading Available"); } if (null == mBestReading || mBestReading.getAccuracy() > MIN_LAST_READ_ACCURACY || mBestReading.getTime() < System.currentTimeMillis() - TWO_MIN) { mLocationClient.requestLocationUpdates(mLocationRequest, this); // Schedule a runnable to unregister location listeners Executors.newScheduledThreadPool(1).schedule(new Runnable() { @Override public void run() { mLocationClient.removeLocationUpdates(LocationGetLocationActivity.this); } }, MEASURE_TIME, TimeUnit.MILLISECONDS); } } } // Get the last known location from all providers // return best reading is as accurate as minAccuracy and // was taken no longer then maxAge milliseconds ago private Location bestLastKnownLocation(float minAccuracy, long maxAge) { Location bestResult = null; float bestAccuracy = Float.MAX_VALUE; long bestTime = Long.MIN_VALUE; // Get the best most recent location currently available mCurrentLocation = mLocationClient.getLastLocation(); if (mCurrentLocation != null) { float accuracy = mCurrentLocation.getAccuracy(); long time = mCurrentLocation.getTime(); if (accuracy < bestAccuracy) { bestResult = mCurrentLocation; bestAccuracy = accuracy; bestTime = time; } } // Return best reading or null if (bestAccuracy > minAccuracy || (System.currentTimeMillis() - bestTime) > maxAge) { return null; } else { return bestResult; } } @Override public void onDisconnected() { Log.i(TAG, "Disconnected. Try again later."); } @Override public void onConnectionFailed(ConnectionResult connectionResult) { Log.i(TAG, "Connection Failed. Try again later."); } private boolean servicesAvailable() { // Check that Google Play Services are available int resultCode = GooglePlayServicesUtil .isGooglePlayServicesAvailable(this); // If Google Play services is available return (ConnectionResult.SUCCESS == resultCode); } // Update display private void updateDisplay(Location location) { mAccuracyView.setText("Accuracy:" + location.getAccuracy()); mTimeView.setText("Time:" + new SimpleDateFormat("MM/dd/yyyy HH:mm:ss", Locale .getDefault()).format(new Date(location.getTime()))); mLatView.setText("Longitude:" + location.getLongitude()); mLngView.setText("Latitude:" + location.getLatitude()); } private void ensureColor() { if (mFirstUpdate) { setTextViewColor(mTextViewColor); mFirstUpdate = false; } } private void setTextViewColor(int color) { mAccuracyView.setTextColor(color); mTimeView.setTextColor(color); mLatView.setTextColor(color); mLngView.setTextColor(color); } }